//! Header for the CarHire class
#ifndef CARHIRE_H
#define CARHIRE_H

#include <list>
#include "Object.h"
#include "ICar.h"

//! CarHire manages all Cars
/*!
	The CarHire class is able to add a new Car to the car rental,
	reserve Cars or move them to available and prints them to ostream.
	\class CarHire
	\author Andreas Lehner
	\date 22.11.2012
*/

//typedefs for the ICar* lists
typedef std::list<ICar*> TCars;
typedef TCars::iterator TCarsIter;

class CarHire : public Object {
public:
	//! Adds a new Car to the car rental
	/*!
		This function adds a ICar* to a list of ICar* with push_back().
		When adding new ICar* it is always added to the list
		of available cars.
		\param car The car that is being added to the list of ICar*
		\throw exception if the pointer is invalid
	*/
	void Add(ICar * car);
	//! Prints all available Cars of the CarHire
	/*!
		All cars that are listed in the list of available cars
		will be printed in the order the cars have been added to the list.
		First element printed = first element added. It is able to print
		the result to any ostream passed through.
		It is printing all information a car has which includes
		Price of the car (including extras), manufacturer, type and its extras.
		\param stream The ostream where the cars will be printed to.
	*/
	void PrintAvailable(std::ostream &stream);
	//! Prints all reserved Cars of the CarHire
	/*!
		All cars that are listed in the list of reserved cars
		will be printed in the order the cars have been added to the list.
		First element printed = first element added. It is able to print
		the result to any ostream passed through.
		It is printing all information a car has which includes
		Price of the car (including extras), manufacturer, type and its extras.
		\param stream The ostream where the cars will be printed to.
	*/
	void PrintReserved(std::ostream &stream);
	//! Get a list of available Cars of the CarHire corresponding to type or manufacturer
	/*!
		This function returns the list of available cars corresponding to
		type or manufacturer. These two values also have default values if the cars of all
		manufacturers and types, respectively should be given back.
		\param type A string holding the type of a car
		\param manufacturer A string holding the manufacturer of a car
		\return TCars A list of ICars* holding the requested cars
	*/
	TCars GetAvailable(std::string const& type="", std::string const& manufacturer="");
	//! Get a list of reserved Cars of the CarHire corresponding to type or manufacturer
	/*!
		This function returns the list of reserved cars corresponding to
		type or manufacturer. These two values also have default values if the cars of all
		manufacturers and types, respectively should be given back.
		\param type A string holding the type of a car
		\param manufacturer A string holding the manufacturer of a car
		\return TCars A list of ICars* holding the requested cars
	*/
	TCars GetReserved(std::string const& type="", std::string const& manufacturer="");
	//! Reserve a Car of the car rental
	/*!
		The function moves an available Car from the list of available cars
		to the list of reserved cars. The Car will be removed on the available list
		and added on the reserved list with push_back().
		\param car The Car that is going to be reserved and is at the moment
		in the list of available cars
		\throw exception if the pointer is invalid
	*/
	void Reserve(ICar * car);
	//! Move a Car of the car rental to available
	/*!
		The function moves a reserved Car from the list of reserved cars
		to the list of available cars. The Car will be removed on the reserved list
		and added on the available list with push_back().
		\param car The Car that is going to be available and is at the moment
		in the list of reserved cars
		\throw exception if the pointer is invalid
	*/
	void MoveToAvailable(ICar * car);

private:
	//! The list of available ICar*'s
	TCars mAvailableCars;
	//! The list of reserved ICar*'s
	TCars mReservedCars;

};

#endif